<?php
/**
 * 渲染模板，并生成html。
 * 会注册_SERVER_ROOT与_title两个变量
 * @param string $template 模板名称
 * @param array $vars 模板要使用的页面变量数组
 */
function rendertpl($template, $vars=null) {
	global $_title, $cf_entry;
	
	$tplpath = ROOT_DIR."/tpl/$template";
	if(!file_exists($tplpath)) {
		myexit($tplpath.' lose.<br />');
	}
	
	//初始化smarty模板引擎
	require_once ROOT_DIR."/lib/smarty/Smarty.class.php";
	
	$html_smarty = new Smarty;
	$html_smarty->template_dir = ROOT_DIR."/tpl/";
	$html_smarty->compile_dir = ROOT_DIR."/cache/ctpl/";
	$html_smarty->config_dir = ROOT_DIR."/conf/";
	$html_smarty->cache_dir = ROOT_DIR."/cache/";
	$html_smarty->plugins_dir[] = ROOT_DIR."/bc";
	
	//注册参数变量
	$html_smarty->assign($vars);
	
	//注册自定义变量，用"v_变量名"访问
//	$globalvariables = getcache('globalvariables');
//	if(!empty($globalvariables)) {
//		foreach($globalvariables as $key => $v) {
//			$html_smarty->assign('v_'.$key, $v);
//		}
//	}
	
	//注册根网址, 标题, 入口页面
	$html_smarty->assign("_SERVER_ROOT", SERVER_ROOT);
	$html_smarty->assign("_title", $_title);
	$html_smarty->assign("_entry", $cf_entry);

	/*
	//注册GET、COOKIE变量
	foreach($_GET as $key => $value) {
		$html_smarty->assign('hg_'.$key, htmlspecialchars($value));
		$html_smarty->assign('g_'.$key, $value);
		$html_smarty->assign('hr_'.$key, htmlspecialchars($value));
		$html_smarty->assign('r_'.$key, $value);
	}
	foreach($_POST as $key => $value) {
		$html_smarty->assign('hp_'.$key, htmlspecialchars($value));
		$html_smarty->assign('p_'.$key, $value);
		$html_smarty->assign('hr_'.$key, htmlspecialchars($value));
		$html_smarty->assign('r_'.$key, $value);
	}
	foreach($_COOKIE as $key => $value) {
		$html_smarty->assign('hc_'.$key, htmlspecialchars($value));
		$html_smarty->assign('c_'.$key, $value);
	}
	
	//注册全局变量
	foreach($GLOBALS as $key => $value){
		if(substr($key, 0, 1)=='_')
			$html_smarty->assign($key, $value);
	}
	//*/
	
	$text = $html_smarty->fetch($template);
	return $text;
}

/**
 * 在logs目录下创建当天的日志文件, 并向其中输出$log信息
 * 
 * @param unknown_type $log
 */
function mylog($log) {
	$logfile = ROOT_DIR.'/logs/'.date('Ymd').'.log';
	
	$time = time();
	$time = date('H:i:s', $time);
	error_log($time."\t".$log."\n", 3, $logfile);
}

/**
 * 把$text写入到文件$filename中。如果$filename指定的路径不存在，则创建之（包括目录）
 * @param unknown_type $text
 * @param unknown_type $filename
 */
function writetofile($text, $filename) {
	$path = pathinfo($filename);
	if(!is_dir($path['dirname'])) {
		mkdir($path['dirname'], 0777, true);
	}
	if(!$fp = fopen($filename, 'w')) {
		return false;
	} else {
		flock($fp, LOCK_EX);
		fwrite($fp, $text);
		fclose($fp);
		return true;
	}
}

/**
 * 返回$filename指定的文件的内容
 * @param unknown_type $filename
 */
function readfromfile($filename) {
	if(substr($filename, 0, 7) != 'http://' && !is_readable($filename)) {
		return '';
	}
	if(PHP_VERSION < '4.3.0') {
		if(!$fp = fopen($filename, 'r')) {
			return false;
		} else {
			flock($fp, LOCK_EX);
			$return = '';
			while (!feof($fp)) {
				$return .= fgets($fp, 4096);
			}
			fclose($fp);
			return $return;
		}
	} else {
		return file_get_contents($filename);
	}
}

/**
 * 更新文件修改时间, 如果文件不存在,则创建$file
 * @param unknown_type $file
 */
function mytouch($file) {
	$dir = dirname($file);
	mkdir($dir, 0777, true);
	touch($file);
}

/**
 * 拷贝, 支持文件与目录级复制
 * @param unknown_type $source
 * @param unknown_type $target
 * @param $includedotheaded 是否拷贝以.(点号)开头的文件(夹)
 */
function mycopy($source, $target, $includedotheaded = TRUE) {
	$targetdir = dirname($target);
	if(!file_exists($targetdir)) mkdir($targetdir, 0777, TRUE);
	if(is_dir($source)) {
		if(!$includedotheaded && (strpos($source, '.') === 0)) return false;
		$mydir = opendir($source);
		if(!file_exists($target)) mkdir($target);
		while(false!==($file = readdir($mydir))) {
			if(!$includedotheaded && (strpos($source, '.') === 0)) continue;
			if((is_dir("$source/$file")) && ($file!=".") && ($file!="..")) {
				if(!mycopy("$source/$file","$target/$file")) return false;
			} elseif(is_file("$source/$file")) {
				if(!copy("$source/$file","$target/$file")) return false;
			}
		}
		return true;
	}
	return copy($source, $target);
}

/**
 * 生成随机码。若$numeric=true,则只生成数字；否则生成目标也包括字母。
 * @param int $length
 * @param bool $numeric
 */
function randomcaptcha($length, $numeric = FALSE) {
	mt_srand((double)microtime() * 1000000);
	if($numeric) {
		$hash = sprintf('%0'.$length.'d', mt_rand(0, pow(10, $length) - 1));
	} else {
		$hash = '';
		$chars = '0123456789abcdefghijklmnopqrstuvwxyz';//ABCDEFGHIJKLMNOPQRSTUVWXYZ
		$max = strlen($chars) - 1;
		for($i = 0; $i < $length; $i++) {
			$hash .= $chars[mt_rand(0, $max)];
		}
	}
	return $hash;
}

//返回: 0:成功; -1:不匹配; 1: 过期
function verifycaptcha($id, $captcha){
	if(isempty(@$_SESSION["CAPTCHAID_$_GET[id]"])){
		return 1;//session过期
	}
	if($_GET['captcha']===$_SESSION["CAPTCHAID_$_GET[id]"])
		return 0;
	else
		return -1;
}

function setcaptcha($id, $captcha){
	$_SESSION["CAPTCHAID_$_GET[id]"] = $captcha;
}

/**
 * 获取url中的文件后缀名
 * 
 * @param unknown_type $filename
 */
function fileext($filename) {
	$ext = strtolower(trim(substr(strrchr($filename, '.'), 1)));
	$offset = strpos($ext, '?');
	if($offset !== false) {
		return substr($ext, 0, $offset);
	} else {
		return $ext;
	}
}

function uploadfile($file, $newname) {
	$file = str_replace('\\\\', '\\', $file);
	if(!is_uploaded_file($file)) return false;
	$path = pathinfo($newname);
	if(!is_dir($path['dirname'])) mkdir($path['dirname'], 0777, TRUE);
	return move_uploaded_file($file, $newname);
}

function ak_ftpput($source, $target, $server = '') {
	global $attachserver;
	static $conn_id = null;
	if(empty($server) && !empty($attachserver)) $server = $attachserver;
	if(empty($server)) return false;
	list($userinfo, $hostinfo) = explode('@', $server);
	list($user, $pass) = explode(':', $userinfo);
	$dir = '';
	if(false!==($offset = strpos($hostinfo, '/'))) {
		$dir = substr($hostinfo, $offset);
		$hostinfo = substr($hostinfo, 0, $offset);
	}
	if(strpos($hostinfo, ':') === false) {
		$host = $hostinfo;$port = 21;
	} else {
		list($host, $port) = explode(':', $hostinfo);
	}
	list($user, $pass) = explode(':', $userinfo);
	$key = md5($server, 1);
	if(empty($conn_id[$key])) {
		$conn_id[$key] = ftp_connect($host, $port);
		if($conn_id[$key] === false) return false;
		ftp_login($conn_id[$key], $user, $pass);
		if($dir != '') ftp_chdir($conn_id[$key], $dir);
	}
	return ftp_put($conn_id[$key], $target, $source, FTP_BINARY);
}

/**
 * 向浏览器返回一个可以自动刷新页面的脚本.
 * 
 * @param unknown_type $timeout
 */
function refreshself($timeout=10) {
	$script = "<script language='javascript'>setTimeout(\"document.location.reload()\", $timeout);</script>";
	myexit($script);
}

function unaddslashes($str) {
	global $charset;
	if(is_array($str)) {
		foreach($str as $key => $val) {
			$str[$key] = unaddslashes($val);
		}
	} else {
		$str = stripslashes($str);
	}
	return $str;
}

function sqlite_addslashes($value) {
	if(is_array($value)) {
		foreach($value as $k => $v) {
			$value[$k] = sqlite_addslashes($v);
		}
	} else {
		if(function_exists('sqlite_escape_string')) {
			$value = sqlite_escape_string($value);
		} else {
			$value = str_replace("'", "''", $value);
		}
	}
	return $value;
}

function gbk_addslashes($text) {
	if(!function_exists('mb_strpos')) return addslashes($text);
	if(strpos($text, '\\') === false) return addslashes($text);
	$ok = '';
	while(1) {
		$i = mb_strpos($text, chr(92), 0, 'GBK');
		if($i === false) break;
		$t = mb_substr($text, 0, $i, 'GBK').chr(92).chr(92);
		$text = substr($text, strlen($t) - 1);
		$ok .= $t;
	}
	$text = $ok.$text;
	$text = str_replace(chr(39), chr(92).chr(39), $text);
	$text = str_replace(chr(34), chr(92).chr(34), $text);
	return $text;
}

function gbk_stripslashes($text) {
	$text = str_replace(chr(92).chr(34), chr(34), $text);
	$text = str_replace(chr(92).chr(39), chr(39), $text);
	$ok = '';
	while(1) {
		$i = mb_strpos($text, chr(92).chr(92), 0, 'GBK');
		if($i === false) break;
		$t = mb_substr($text, 0, $i, 'GBK').chr(92);
		$text = substr($text, strlen($t) + 1);
		$ok .= $t;
	}
	$text = $ok.$text;
	return $text;
}

function ak_utf8_encode($var) {
	if(is_array($var)) {
		foreach($var as $id => $value) {
			$var[$id] = ak_utf8_encode($value);
		}
		return $var;
	} else {
		return iconv('GBK', 'UTF-8//IGNORE', $var);
	}
}

function utf8togbk($var) {
	if(is_array($var)) {
		foreach($var as $id => $value) {
			$var[$id] = utf8togbk($value);
		}
		return $var;
	} else {
		return iconv('UTF-8', 'GBK//IGNORE', $var);
	}
}

function gbktoutf8($var) {
	if(is_array($var)) {
		foreach($var as $id => $value) {
			$var[$id] = gbktoutf8($value);
		}
		return $var;
	} else {
		return iconv('GBK', 'UTF-8//IGNORE', $var);
	}
}

/**
 * 对$str进行分解（用$separator）解析，剔除重复的、空的项。
 * @param $str
 * @param $separator 分隔符，默认,（逗号）
 */
function tidyitemlist($str, $separator = ',') {
	$array = explode($separator, $str);
	$array = array_unique($array);
	$array2 = array();
	foreach($array as $item) {
		$item = trim($item);
		if($item != '' && !in_array($item, $array2) ) {
			$array2[] = $item;
		}
	}
	return implode($separator, $array2);
}

function ak_replace($find, $replace, $str, $caseless = 1, $count = -1) {//$caseless�Ƿ���ִ�Сд��0Ϊ�����
	if(!is_array($find)) {
		$find = array($find);
	}
	if(!is_array($replace)) {
		$replace = array($replace);
	}
	if(count($find) != count($replace)) return false;
	if($caseless == 1) {
		foreach($find as $id => $f) {
			if($f == '') continue;
			if(strpos($str, $f) === false) continue;
			$str = str_replace_count($f, $replace[$id], $str, $count);
		}
	} else {
		foreach($find as $id => $f) {
			$f = str_replace('/', '\/', $f);
			if(!preg_match("/{$f}/i", $str)) continue;
			$str = preg_replace("/{$f}/i", $replace[$id], $str, $count);
		}
	}
	return $str;
}

function ak_array_replace($finds, $replaces, $str) {
	$_str = $str;
	foreach($finds as $key => $value) {
		$r = '';
		if(isset($replaces[$key])) $r = $replaces[$key];
		$_str = ak_replace($value, $r, $_str);
	}
	return $_str;
}

function str_replace_count($search, $replace, $string, $count) {
	if($count < 0) {
		return str_replace($search, $replace, $string);
	} elseif($count == 0) {
		return $string;
	} else {
		return str_replace_count($search, $replace, str_replace_once($search, $replace, $string), $count - 1);
	}
}

function str_replace_once($search, $replace, $string) {
	$pos = strpos($string, $search);
	if($pos === false) return true;
	$return = '';
	$s1 = substr($string, 0, $pos);
	$s2 = substr($string, $pos + strlen($search));
	return $s1.$replace.$s2;
}

function in_string($string, $findme) {
	if(is_string($findme)) {
		$pos = strpos($string, $findme);
		if($pos === false) return false;
		return true;
	}
	
	if(!is_array($findme)) return false;
	foreach($findme as $find) {
		$find = trim($find);
		if($find == '') continue;
		if(strpos($string, $find) !== false) return true;
	}
	return false;
}

/**
 * 将$array进行html特殊字符处理，如<换成&lt;
 */
function myhtmlspecialchars($array) {
	if(!is_array($array) && !is_object($array)) {
		$isvariable = 1;
		$array = array($array);
	}
	foreach($array as $key => $value) {
		if(is_array($value)) {
			$array[$key] = myhtmlspecialchars($value);
		} elseif(is_object($value)) {
			$array[$key] = myhtmlspecialchars(get_object_vars($value));
		} else {
			$array[$key] = htmlspecialchars($value);
		}
	}
	if(!isset($isvariable)) {
		return $array;
	} else {
		return $array[0];
	}
}

/**
 * 封装MD5。
 * @param $short 是否使用短串（[8-24)），默认不使用
 * @param $time md5多少次，默认1次
 */
function mymd5($string, $short = false, $time = 1) {
	$md5 = $string;
	for($i = $time; $i >= 1; $i --) {
		$md5 = md5($md5);
	}
	if(!$short) return $md5;
	return substr($md5, 8, 16);
}

/**
 * 读取$dir目录下的所有文件路径。如果$shortfilename=true，那么将只返回文件名
 */
function readpathtoarray($dir, $shortfilename = 0) {
	$return = array();
	if(!file_exists($dir)) return $return;
	$fp = opendir($dir);
	while (false !== ($file = readdir($fp))) {
		if($file == '.' || $file == '..') continue;
		if($shortfilename == 1) {
			$return[] = $file;
		} else {
			if(substr($dir, -1) == '/') {
				$return[] = $dir.$file;
			} else {
				$return[] = $dir.'/'.$file;
			}
		}
	}
	closedir($fp);
	return $return;
}

/**
 * 将$str进行编码转换
 * 
 * @param unknown_type $from
 * @param unknown_type $to
 * @param unknown_type $str 字符串或字符串数组
 */
function myiconv($from, $to, $str) {
	if(function_exists('iconv')) {
		if(is_array($str)) {
			foreach($str as $key => $value) {
				$str[$key] = myiconv($from, $to, $value);
			}
			return $str;
		} elseif(is_string($str)) {
			return iconv($from, $to, $str);
		}
	} else {
		return $str;
	}
}

/**
 * 获取url中的query参数。
 * 
 * @param unknown_type $url
 */
function getreqparam($url) {
	$return = array();
	$parsed = parse_url($url);
	if(!isset($parsed['query'])) return array();
	$array_query = explode('&', $parsed['query']);
	foreach($array_query as $query) {
		$keyvalue = explode('=', $query);
		if(isset($keyvalue[1])) {
			$return[$keyvalue[0]] = $keyvalue[1];
		}
	}
	return $return;
}

/**
 * 读取url指定的资源
 */
function readfromurl($url, $convertcharset = 0) {
	$charset = "utf8";
	$agent = 'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; KILIHORSE)';
	if(!empty($GLOBALS['wget'])) {
		$_tmp = ROOT_DIR.'cache/'.md5($url);
		system("wget --timeout=10 --tries=3 --no-check-certificate --user-agent=\"$agent\" -q -O {$_tmp} \"".$url."\"");
		$content = readfromfile($_tmp);
		@unlink($_tmp);
		//echo "wget\n";
	} elseif(function_exists('curl_init')) {
		$ch = curl_init();
		curl_setopt($ch, CURLOPT_URL, $url);
		curl_setopt($ch, CURLOPT_HEADER, 0);
		curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
		@curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
		curl_setopt($ch, CURLOPT_USERAGENT, $agent);
		$content = curl_exec($ch);
		curl_close($ch);
		//echo "curl\n";
	} elseif(function_exists('fsockopen')) {
		$offset = strpos($url, '://');
		if($offset === false) return false;
		if(strpos($url, '/', $offset + 3) === false) $url .= '/';
		$host = getfield1('://', '/', $url);
		$request =  "GET ".$url." HTTP/1.0\r\n";
		$request .= "Host: ".$host."\r\n";
		$request .= "Accept: */*\r\n";
		$request .= "User-Agent: {$agent}\r\n\r\n";
		$sHnd = @fsockopen($host, 80, $errno, $errstr, 30);
		if(!$sHnd) return false;
		@fputs($sHnd, $request);
		$content = '';
		while(!feof($sHnd)) {
			$content .= fgets($sHnd, 4096);
		}
		fclose($sHnd);
		$offset = strpos($content, "\r\n\r\n");
		if($offset != false) $content = substr($content, $offset + 4);
		//echo "fsockopen\n";
	} elseif(ini_get('allow_url_fopen') == '1') {
		@ini_set('user_agent', $agent);
		$content = readfromfile($url);
		//echo "url_open\n";
	} else {
		return 'ERROR:spider disabled!';
	}
	if(!empty($convertcharset)) {
		if(strpos(strtolower($content), 'charset=gb') !== false ) {
			$content = gbktoutf8($content);
		}
	}
	return $content;
}


function getfield1($start, $end, $content, $repeatsplit = '') {
	if(empty($content)) return false;
	$return = '';
	while(1) {
		$start_position = 0;
		$end_position = strlen($content);
		if($start != '') $start_position = strpos($content, $start);
		if($start_position === false) break;
		$start_position += strlen($start);
		if($end != '') $end_position = strpos($content, $end, $start_position);
		if($end_position === false) break;
		$return .= substr($content, $start_position, $end_position - $start_position);
		if(empty($repeatsplit)) return $return;
		$return .= $repeatsplit;
		$content = substr($content, $end_position + strlen($end));
	}
	if(strlen($return) > strlen($repeatsplit)) $return = substr($return, 0, strlen($return) - strlen($repeatsplit));
	return $return;
}


/**
 * 清除html中的冗余空白符
 * 
 * @param unknown_type $html
 * @param unknown_type $force
 */
function clearhtml($html, $force = 0) {
	$html = str_replace("\r", '', $html);
	$html = str_replace("\n", '', $html);
	$html = preg_replace('/\s+/', ' ', $html);
	$html = str_replace("> <", '><', $html);
	return $html;
}

/**
 * 删除目录. 可支持不为空删除, 默认开启, 表示即使该目录不为空,也会全部删除
 * 
 * @param unknown_type $dir
 * @param unknown_type $delifnotempty 如果不为空, 是否删除. 默认删除
 */
function myrmdir($dir, $delifnotempty=TRUE) {
	if(!file_exists($dir)) return;
	if(false!==($handle = opendir("$dir"))) {
		while(false !== ($item = readdir($handle))) {
		if($item != "." && $item != "..") {
			if(is_dir("$dir/$item")) {
				myrmdir("$dir/$item");
			} else {
				unlink("$dir/$item");
			}
		}
	}
	closedir($handle);
	rmdir($dir);
	}
}

function getdomain($url) {//��url�н�ȡ����
	$p1 = strpos($url, '://') + 3;
	$p2 = strpos($url, '/', $p1);
	return substr($url, $p1, $p2 - $p1);
}

function geturlpath($url) {
	if(substr($url, -1) == '/') return $url;
	$pos = mystrrpos($url, '/'); return substr($url, 0, $pos + 1);
}

/**
 * 封装不同版本php对strrpos的支持
 */
function mystrrpos($string, $findme) {
	if(PHP_VERSION < '5.0') {
		$string = strrev($string);
		$findme = strrev($findme);
		$_pos1 = strpos($string, $findme);
		return strlen($string) - $_pos1 - strlen($findme);
	} else {
		return strrpos($string, $findme);
	}
}

/**
 * 获取不同语言的文字
 * 
 * @param unknown_type $charset
 * @param unknown_type $language
 */
function lan($charset, $language = 'english') {
	if($language == 'english') $charset = 'english';
	$languagefilename = ROOT_DIR."configs/language/{$language}/{$charset}.lan";
	if(!file_exists($languagefilename)) myexit($charset.$language.' language not exist');
	$lan = array();
	$landata = readfromfile($languagefilename);
	$array = explode("\n", $landata);
	foreach($array as $_line) {
		$_fields = explode("\t", $_line);
		if(count($_fields) != 2) continue;
		$lan[$_fields[0]] = $_fields[1];
	}
	return $lan;
}

function ak_xor($string, $key = '') {
	if('' == $string) return '';
	if('' == $key) $key = 'akcms';
	$len1 = strlen($string);
	$len2 = strlen($key);
	if($len1 > $len2) $key = str_repeat($key, ceil($len1 / $len2));
	return $string ^ $key;
}

function sendmail($to, $subject, $html) {
	global $smtp;
	require_once ROOT_DIR.'include/mail.func.php';
	if(!isset($smtp)) $smtp = new smtp();
	$result = $smtp->sendmail($to, $subject, $html);
	if($result === false) {
		mylog('Send Mail to :'.$to.' ERROR!');
		unset($smtp);
		return false;
	}
	mylog('Send Mail to: '.$to.' success!');
}

function postrequest($url, $params = array(), $postfield = '') {
	if(!empty($postfield)) {
		$str = $postfield;
	} else {
		$str = '';
		foreach($params as $k => $v) {
			$str .= '&'.$k.'='.urlencode($v);
		}
		$str = substr($str, 1);
	}
	$error = 1;
	if(function_exists('curl_init') && 0) {
		$ch = curl_init();
		curl_setopt($ch, CURLOPT_POST, 1);
		curl_setopt($ch, CURLOPT_URL, $url);
		curl_setopt($ch, CURLOPT_POSTFIELDS, $str);
		curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
		curl_setopt($ch, CURLOPT_USERAGENT, '');
		$result = curl_exec($ch);
		$errno = curl_errno($ch);
		curl_close($ch);
	} else {
		$context = array(
			'http' => array(
				'method' => 'POST',
				'header' => "Content-type: application/x-www-form-urlencoded\r\nUser-Agent:\r\nContent-length:".strlen($str),
				'content' => $str
			)
		);
		$contextid = stream_context_create($context);
		$sock = fopen($url, 'r', false, $contextid);
		if($sock){
			$errno = 0;
			$result = '';
			while(!feof($sock)) {
				$result .= fgets($sock, 4096);
			}
			fclose($sock);
		}
	}
	return array(
		'errno' => $errno,
		'result' => $result
	);
}

/**
 * 解压zip文件
 * @param $zip zip文件路径
 * @param $to 解压到哪个目录
 */
function unzip($zip, $to = '.') {
	$size = filesize($zip);
	$maximum_size = min(277, $size);
	$fp = fopen($zip, 'rb');
	fseek($fp, $size - $maximum_size);
	$pos = ftell($fp);
	$bytes = 0x00000000;
	while($pos < $size) {
		$byte = fread($fp, 1);
		if(PHP_INT_MAX > 2147483647) {
			$bytes = ($bytes << 32);
			$bytes = ($bytes << 8);
			$bytes = ($bytes >> 32);
		} else {
			$bytes = ($bytes << 8);
		}
		$bytes = $bytes | ord($byte);
		if($bytes == 0x504b0506) {
			$pos ++;
			break;
		}
		$pos ++;
	}
	$fdata = fread($fp, 18);
	$data = @unpack('vdisk/vdisk_start/vdisk_entries/ventries/Vsize/Voffset/vcomment_size',$fdata);
	$pos_entry = $data['offset'];
	for($i=0; $i < $data['entries']; $i++) {
		fseek($fp, $pos_entry);
		$header = ReadCentralFileHeaders($fp);
		$header['index'] = $i;
		$pos_entry = ftell($fp);
		rewind($fp);
		fseek($fp, $header['offset']);
		$stat[$header['filename']] = ExtractFile($header, $to, $fp);
	}
	fclose($fp);
}

function ReadCentralFileHeaders($fp) {
	$binary_data = fread($fp, 46);
	$header = unpack('vchkid/vid/vversion/vversion_extracted/vflag/vcompression/vmtime/vmdate/Vcrc/Vcompressed_size/Vsize/vfilename_len/vextra_len/vcomment_len/vdisk/vinternal/Vexternal/Voffset', $binary_data);
	$header['filename'] = $header['extra'] = $header['comment'] = '';
	if($header['filename_len'] != 0) $header['filename'] = fread($fp, $header['filename_len']);
	if($header['extra_len'] != 0) $header['extra'] = fread($fp, $header['extra_len']);
	if($header['comment_len'] != 0) $header['comment'] = fread($fp, $header['comment_len']);
	$header['mtime'] = time();
	$header['stored_filename'] = $header['filename'];
	$header['status'] = 'ok';
	if(substr($header['filename'], -1) == '/') $header['external'] = 0x41FF0010;
	return $header;
}

function ReadFileHeader($fp) {
	$binary_data = fread($fp, 30);
	$data = unpack('vchk/vid/vversion/vflag/vcompression/vmtime/vmdate/Vcrc/Vcompressed_size/Vsize/vfilename_len/vextra_len', $binary_data);

	$header['filename'] = fread($fp, $data['filename_len']);
	if ($data['extra_len'] != 0) {
	  $header['extra'] = fread($fp, $data['extra_len']);
	} else { $header['extra'] = ''; }

	$header['compression'] = $data['compression'];
	$header['size'] = $data['size'];
	$header['compressed_size'] = $data['compressed_size'];
	$header['crc'] = $data['crc']; $header['flag'] = $data['flag'];
	$header['mdate'] = $data['mdate'];
	$header['mtime'] = $data['mtime'];

	if ($header['mdate'] && $header['mtime']){
	 $hour=($header['mtime']&0xF800)>>11;$minute=($header['mtime']&0x07E0)>>5;
	 $seconde=($header['mtime']&0x001F)*2;$year=(($header['mdate']&0xFE00)>>9)+1980;
	 $month=($header['mdate']&0x01E0)>>5;$day=$header['mdate']&0x001F;
	 $header['mtime'] = mktime($hour, $minute, $seconde, $month, $day, $year);
	}else{$header['mtime'] = time();}

	$header['stored_filename'] = $header['filename'];
	$header['status'] = "ok";
	return $header;
}

function ExtractFile($header, $to, $fp) {
	$header = readfileheader($fp);
	if(substr($to, -1) != '/') $to .= '/';
	if($to == './') $to = '';
	if(substr($to, 0, 1) == '/') $to = '.'.$to;
	$to = $to.$header['filename'];
	if(substr($to, -1) == '/') {
		mkdir($to, 0777, true);
	} else {
		$path = pathinfo($to);
		if(!is_dir($path['dirname'])) mkdir($path['dirname'], 0777, true);
	}
	if(strrchr($header['filename'],'/')=='/') return 1;
	if($header['compression'] == 0) {
		$nfp = fopen($to, 'wb');
		if(!$nfp) return(-1);
		$size = $header['compressed_size'];
		while ($size != 0) {
			$read_size = ($size < 2048 ? $size : 2048);
			$buffer = fread($fp, $read_size);
			$binary_data = pack('a'.$read_size, $buffer);
			@fwrite($nfp, $binary_data, $read_size);
			$size -= $read_size;
		}
		fclose($nfp);
	} else {
		$nfp = fopen($to.'.gz', 'wb');
		if(!$nfp) return -1;
		$binary_data = pack('va1a1Va1a1', 0x8b1f, Chr($header['compression']), Chr(0x00), time(), Chr(0x00), Chr(3));
		fwrite($nfp, $binary_data, 10);
		$size = $header['compressed_size'];
		while($size != 0) {
			$read_size = ($size < 1024 ? $size : 1024);
			$buffer = fread($fp, $read_size);
			$binary_data = pack('a'.$read_size, $buffer);
			fwrite($nfp, $binary_data, $read_size);
			$size -= $read_size;
		}
		$binary_data = pack('VV', $header['crc'], $header['size']);
		fwrite($nfp, $binary_data,8);
		fclose($nfp);
		$gzp = gzopen($to.'.gz', 'rb');
		if(!$gzp) return(-2);
		$nfp = fopen($to, 'wb');
		if(!$nfp) return(-1);
		$size = $header['size'];
		while($size != 0) {
			$read_size = ($size < 2048 ? $size : 2048);
			$buffer = gzread($gzp, $read_size);
			$binary_data = pack('a'.$read_size, $buffer);
			@fwrite($nfp, $binary_data, $read_size);
			$size -= $read_size;
		}
		fclose($nfp);
		gzclose($gzp);
		unlink($to.'.gz');
	}
	return true;
}

function ak_hmac($algo, $data, $key, $raw_output = false) {
	if(function_exists('hash_hmac')) {
		return hash_hmac($algo, $data, $key, $raw_output);
	} else {
		$algo = strtolower($algo);
		$pack = 'H'.strlen($algo('test'));
		$size = 64;
		$opad = str_repeat(chr(0x5C), $size);
		$ipad = str_repeat(chr(0x36), $size);
		if (strlen($key) > $size) {
			$key = str_pad(pack($pack, $algo($key)), $size, chr(0x00));
		} else {
			$key = str_pad($key, $size, chr(0x00));
		}
		for ($i = 0; $i < strlen($key) - 1; $i++) {
			$opad[$i] = $opad[$i] ^ $key[$i];
			$ipad[$i] = $ipad[$i] ^ $key[$i];
		}
		$output = $algo($opad.pack($pack, $algo($ipad.$data)));
		return ($raw_output) ? pack($pack, $output) : $output;
	}
}

function urlencode_rfc3986($input) {
	if (is_array($input)) {
		foreach($input as $k => $v) {
			$input[$k] = urlencode_rfc3986($v);
		}
		return $input;
	} else if (is_scalar($input)) {
		return str_replace('+', ' ', str_replace('%7E', '~', rawurlencode($input)));
	} else {
		return '';
	}
}

/**
 *生成静态html并返回
 */
function gen_html($filepath){
	if(!file_exists($filepath)) {
		error_log("不存在的$filepath");
		return "";
	}

	extract($GLOBALS);
	ob_start();
	include($filepath);
	$html = ob_get_contents();
	ob_end_clean();
	
	error_log("生成静态html成功,使用的模板是:$filepath");
	return $html;
}

/**
 * 解析排序
 * @param unknown_type $rule
 */
function order_operate($rule) {
	$orderby = "";
	$orders = explode(",",$rule);
	foreach($orders as $order){
		$tmp = explode("_", $order);
		$field = trim($tmp[0]);
		if(!empty($field)) $orderby .= ",$field ";
		else continue;
		
		$dir = strtolower($tmp[1]);
		if("desc"==$dir || "reverse"==$dir) $orderby .= " desc ";
	}
	if(!empty($orderby)) $sqlorderby = " order by ".substr($orderby, 1);
	
	return $sqlorderby;
}

/**
 * 关闭数据库，退出脚本执行
 * @param unknown_type $text
 */
function myexit($text = '') {
	global $db;
	if(isset($db)) $db->close();
	exit(''.$text);
}

/*
function akincludeurl($params) {
	global $host;
	if(!isset($params['url'])) return;
	if(substr($params['url'], 0, 1) == '/') $params['url'] = 'http://'.$host.$params['url'];
	if(strpos($params['url'], 'http://') === false) return;
	if(!isset($params['expire'])) echo readfromurl($params['url']);
	if(isset($params['expire'])) {
		$params['type'] = 'url';
		$data = getcachedata($params);
		if($data == '') {
			$data = readfromurl($params['url']);
			setcachedata($params, $data);
		}
		echo $data;
	}
}

function createthumb($image, $thumb) {
	global $setting_attachmentthumbsize;
	require_once(ROOT_DIR.'include/image.func.php');
	return corecreatethumb($image, $thumb, $setting_attachmentthumbsize);
}

function cloudkeywords($title, $content) {
	$cloudurl = 'http://service.akcms.com/cal_keywords.php';
	$result = postrequest($cloudurl, array('title' => $title, 'content' => $content));
	return unserialize($result['result']);
}
//*/

/**
 * 用特定日期格式解析日期字符串, 返回unix时间戳. 出错则返回-1;
 * 默认用"Y-m-d H:i:s"格式, 如"2011-01-09 02:11:03"
 * 格式化字符串中只能用YmdHis这几个时间字符,分隔符不限
 */
function parsedate($datestr, $format=null){
	if(isempty($datestr)) return 0;
	
	if(isempty($format)) $format = "Y-m-d H:i:s";
	
	if(PHP_VERSION>'5.3.0' ){
		$res = date_parse_from_format($format, $datestr);
		return mktime($res['hour'], $res['minute'], $res['second'], $res['month'], $res['day'], $res['year']);
	}
	else{
		$format = str_replace("d", '(?P<d>\d{2})', $format);
		$format = str_replace("Y", '(?P<Y>\d{4})', $format);
		$format = str_replace("m", '(?P<m>\d{2})', $format);
		$format = str_replace("H", '(?P<H>\d{2})', $format);
		$format = str_replace("i", '(?P<i>\d{2})', $format);
		$format = str_replace("s", '(?P<s>\d{2})', $format);
		preg_match("/$format/", $datestr, $res);
		return mktime($res['H'], $res['i'], $res['s'], $res['m'], $res['d'], $res['Y']);
	}
}

/**
 * 发送短信.
 * @param $toes 目标号码数组
 */
function sendsms($toes, $content){
	global $_sms;
	$smses = $_sms->sendsms($toes, $content);
	if(is_array($smses)){
		include_once ROOT_DIR.'/bc/block.sms.php';
		insertsms($smses);
		return true;
	}
	return false;
}

/**
 * 接收短信.
 */
function recvsms(){
	global $_sms;
	$smses = $_sms->recvsms();
	if(is_array($smses)){
		include_once ROOT_DIR.'/bc/block.sms.php';
		insertsms($smses);
		return true;
	}
	
	return false;
}

/**
 * 通用的获取bc结果集的方法. 只支持在1:1中的双方和1:M中M的一方上做的查询
 * @param string $bcname bc的名称(表名,不带t_)
 * @param array(string) $params 参数
 * @param array(string) $joinfields join字段集, 可不设置
 * @param array(string) $joinspecs join规范,可用alias, 如hah:lov.id=id中hah是别名
 * @param string $sqlwhere 用于sql where中, 默认支持id查询
 * @param string $sqlorderby 用于sql order by中
 * getcommbc("demo", $params, array('lov.name', 'hah.name'),array('lov.id=id','hah:lov.id=id'), "", "")
 */
function getcommbc($bcname, &$params, $joinfields=null, $joinspecs=null, $sqlwhere="", $sqlorderby=""){
	global $_db, $cf_pagenum;
	
	//#region 构建sql
	
	//#region获取自身可访问的字段列表
	$fieldparams = array("bc"=>$bcname, "pagenum"=>-1);
	$selffieldrows = getfield($fieldparams);
	$selectlist = "";
	foreach($selffieldrows as $row){
		$selectlist .= "t_$bcname.c_$row[field],";
	}
	if(empty($selectlist)){
		error_log("{$bcname}自身没有可访问的字段");
		return null;
	}
	//#endreg 获取可访问的字段列表
	
	//处理join语句. 注意本表自身不需要指定alias与表名,只需要提供字段名即可. 如本表是demo, 一表是a, 则join关系表达式可能是"asa:a.id=id"
	//如果两边都有前缀,那么以左边为基准. 如"asa:a.id=asb:b.id"则对应与"left join a asa on asa.id=asb.id"
	//如果只有一边都有前缀,那么以有前缀的边为基准. 如"asa:a.id=asb.id"则对应与"left join a asa on asa.id=asb.id"
	if(isset($joinspecs)){
		$sqljoin = "";
		foreach($joinspecs as $join){
			$parts = explode("=", $join);
			$partl = explode(".", $parts[0]);
			$partr = explode(".", $parts[1]);
			if(count($partl)<=1 && count($partr)<=1) error_log("join参数不合法, 至少有一个需要指定对象");
			else{
				if(count($partr)==2){
					$rfield = $partr[1];
					$start = strpos($partr[0], ":");
					if(false!==$start){
						$ralias = substr($partr[0], 0, $start);
						$rtable = substr($partr[0], $start+1);
						$aliastable[$ralias] = $rtable;
					}
					else{
						$ralias = $partr[0];
						$rtable = null;
					}
				}
				else{
					$rfield = $partr[0];
				}
				
				if(count($partl)==2){
					$lfield = $partl[1];
					$start = strpos($partl[0], ":");
					if(false!==$start){
						$lalias = substr($partl[0], 0, $start);
						$ltable = substr($partl[0], $start+1);
						$aliastable[$lalias] = $ltable;
					}
					else{
						$lalias = $partl[0];
						$ltable = null;
					}
				}
				else{
					$lfield = $partl[0];
				}
				
				if(count($partl)==1){
					$sqljoin .= " left join t_$rtable $ralias on $ralias.c_$rfield=t_$bcname.c_$lfield";
				}
				else if(count($partr)==1){
					$sqljoin .= " left join t_$ltable $lalias on $lalias.c_$lfield=t_$bcname.c_$rfield";
				}
				else{
					if(null==$ltable)
						$sqljoin .= " left join t_$rtable $ralias on $ralias.c_$rfield=$lalias.c_$lfield";
					else
						$sqljoin .= " left join t_$ltable $lalias on $lalias.c_$lfield=$ralias.c_$rfield";
				}
			}
		}
	}
	
	//处理join字段
	if(isset($joinfields)){
		foreach($joinfields as $jfield){
			$aliasfield = explode(".", $jfield);
			$len = count($aliasfield);
			$alias = $aliasfield[$len-2];
			$field = $aliasfield[$len-1];
			
			//判断该字段是否能访问
			$fieldparams = array("bc"=>$aliastable[$alias], "field"=>$field,"pagenum"=>-1);
			$fieldrows = getfield($fieldparams);
			if(isempty($fieldrows))
				continue;
				
			$selectlist .= "$alias.c_$field as '$jfield',";
		}
	}
	$selectlist = substr($selectlist, 0, -1);
	
	$sql = "select $selectlist from t_$bcname $sqljoin where 1=1 ";
	$countsql = "select count(*) from t_$bcname $sqljoin where 1=1 ";//获得条件约束下的结果集的所有行数，用于分页
	
	//#region 条件处理
	if(array_key_exists("id", $params)) $sqlwhere .= " and t_$bcname.c_id = '$params[id]' ";
	if(!empty($sqlwhere)) $sqlwhere = " and $sqlwhere ";
	//#endreg 条件处理

	//#region 排序处理
	if(empty($sqlorderby)){
		$sqlorderby = " order by t_$bcname.c_updated desc";
	}
	//#endreg 排序处理
	
	//获取总数
	$countsql .= " $sqlwhere $sqlorderby";
	$totalcount = $_db->get1stcolval($countsql);
	$params['totalcount'] = $totalcount;//将总数放入params中以备分页所用
	
	//#region 分页处理
	$limit = "";
	if(!array_key_exists("pagenum", $params)){
		$params['pagenum'] = $cf_pagenum;
	}
	if(0>=$params['pagenum']){
		$params['pagenum'] = $totalcount;
		$params['pageindex'] = 0;
	}
	$params['pageindex'] = (!isset($params['pageindex']) || $params['pageindex']<0)?0:(int)$params['pageindex'];
	$maxpageindex = @(int)(($totalcount - 1)/$params['pagenum']);
	if($maxpageindex <= 0) $maxpageindex = 0;
	if($params['pageindex'] > $maxpageindex) $params['pageindex'] = $maxpageindex;
	$start = $params['pageindex']*$params['pagenum'];	
	$limit = " limit $start, $params[pagenum]";
	//#endreg 分页处理
	
	//组装sql
	$sql .= " $sqlwhere $sqlorderby $limit";
	//error_log($sql);
	//#endreg 构建sql
	
	//获取结果集
	$rows = $_db->query($sql);
	
	
	
	//#region 处理结果集
	//如果结果集为空且设置了alwaysonce参数为true, 则添加一条空记录
	if(0==$totalcount && true==@$params['alwaysonce']){
		$row = array();
		foreach($selffieldrows as $field){
			$row["$field[field]"] = "";
		}
		if(isset($joinfields)){
			foreach($joinfields as $field){
				$row[$field] = "";
			}
		}
		//error_log("newrow:".print_r($row,1));
		$rows[] = $row;
	}
	
	//error_log(print_r($rows,1));
	//处理join字段, 将其放入join表的对象中, 如"lov"=>array("name"=>'')
	if(isset($joinfields)){
		foreach($joinfields as $field){
			foreach($rows as &$row){
				if(array_key_exists($field, $row)){
					$bcfield = explode(".", $field);
					$len = count($bcfield);
					
					$tmp = & $row;
					for($i=0; $i<$len; ++$i){
						if($i==$len-1){
							$tmp[$bcfield[$i]] = $row[$field];
							//error_log("tmp:".print_r($tmp,1));
							unset($row[$field]);
							break;
						}
						elseif(!array_key_exists($bcfield[$i], $tmp)){
							$tmp[$bcfield[$i]] = array();
						}
						$tmp = & $tmp[$bcfield[$i]];
					}
				}
			}
		}
	}
	//error_log(print_r($rows,1));
	//#endreg 处理结果集
	//error_log("rows:".print_r($rows,1));
	return $rows;
}

/**
 * 大致同系统的empty. 但对0, "0"不认为是empty
 */
function isempty($var){
	if(!empty($var))
		return false;
	else{
		if(0===$var || "0"===$var)
			return false;
		else 
			return true;
	}
}

/**
 * 判断数组中是否存在key, 支持多级. 如传入"$arr.a.b"
 */
function exists($str){
	if(isempty($str)) return false;
	$parts = explode(".", $str);
	$len = count($parts);
	
	$var = $parts[0];
	for($i=1; $i<$len; ++$i){
		if(isempty($parts[i])) continue;
		$var .= "['$parts[i]']";
	}
	
	
}
?>
